

package tomkitty;

import java.util.*;
import java.io.*;

public class TkAuthenticationHandler extends Turdlet
  implements AuthenticationHandler {

  protected static Properties passwd = null;
  protected static Hashtable<String, String> realms = null;
  protected Configuration config;

  public Handler init(Handler handler, AppContext context) {
    super.init(handler, context);

    config = context.getConfig();

    if (passwd == null) {
      passwd = new Properties();
      realms = new Hashtable<String, String>();

      Debug.p("Loading authentication:");
      FileInputStream fis = null;
      try {
        fis = new FileInputStream(config.get(CONF_AUTH_CONFIG));
        
        passwd.loadFromXML(fis);
        fis.close();

        Enumeration i = passwd.propertyNames();
        while (i.hasMoreElements()) {
          String name = (String) i.nextElement();
          String realm = passwd.getProperty(name);
          if (name.indexOf(':') == -1) {
            Debug.p("loaded '" + name + "' on realm '" + realm + "'");
            realms.put(name, realm);
          }
        }
      } catch (Exception e) {
        Debug.e("can't load config: " + e.getMessage());
        try {
          fis.close();
        } catch (Exception o_e) {
        }
      }
      Debug.p("");
    }

    return this;
  }

  public void doit() {
    String path = request.getUri().getPath();

    Enumeration<String> i = realms.keys();
    while (i.hasMoreElements()) {
      String rpath = i.nextElement();
      
      if (path.startsWith(rpath)) {
        String realm = realms.get(rpath);
        String creds = request.getField("Authorization");

        try {
          if (creds == null) {
            throw new TkResponseException(HTTP_UNAUTHORIZED);
          }

          String[] userpass = creds.split(" ", 2);

          if (userpass.length < 2 || !userpass[0].equals("Basic")) {
            throw new TkResponseException(HTTP_UNAUTHORIZED);
          }

          String decoded = Base64.decode(userpass[1]);
          String authrealm = passwd.getProperty(decoded);

          if (authrealm == null || ! authrealm.equals(realm)) {
            throw new TkResponseException(HTTP_UNAUTHORIZED);
          }
        } catch (TkResponseException tkr_e) {
          response.setStatus(HTTP_UNAUTHORIZED);
          response.setField("WWW-Authenticate", "Basic realm=\""+realm+"\"");
          break;
        } catch (Exception e) {
          response.setStatus(HTTP_SERVER_ERROR);
          break;
        }
      }
    }
  }

}
